package it.softphone.cmc.server.service.util;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;


/**
 * 
 * 
 * @author softphone
 * 
 * @see java.net.Authenticator
 */
public class BasicHttpUtil {
	public static interface Callback {

		void onSuccess( Reader result );
		
		void onError( Throwable ex );
	}

	private BasicHttpUtil() {}
	
	/**
	 * @param url
	 * @param username
	 * @param password
	 * @throws IOException 
	 */
	public static void get( boolean async, final java.net.URL url, final Callback callback ) throws IOException {
		if( url == null ) throw new IllegalArgumentException( "param url is null");
		if( callback == null ) throw new IllegalArgumentException( "param callabck is null");
		
		final Runnable task = new Runnable() {
			public void run() {

				try {
					URLConnection uc = url.openConnection();
					
					
					InputStream content = (InputStream)uc.getInputStream();
					
					callback.onSuccess(new InputStreamReader (content));
					
					content.close();
					
				} catch (IOException e) {
					callback.onError(e);
				}
				
				
			}
		};
		
		if( async ) {
			new Thread( task, "Request").start();
		}
		else {
			task.run();
		}
		
		
	}
	
	/**
	 * send POST request
	 * 
	 * @param url
	 * @param parameters
	 * @param callback
	 * @throws IOException
	 */
	public static void post( boolean async, final java.net.URL url, final java.util.Map<String,String> parameters, final Callback callback ) throws IOException {
		if( url == null ) throw new IllegalArgumentException( "param url is null");
		if( callback == null ) throw new IllegalArgumentException( "param callabck is null");
		
		
		final Runnable task = new Runnable() {
			public void run() {

				try {
					URLConnection uc = url.openConnection();
				    // Let the run-time system (RTS) know that we want input.
				    uc.setDoInput (true);
				    // Let the RTS know that we want to do output.
				    uc.setDoOutput (true);
				    // No caching, we want the real thing.
				    uc.setUseCaches (false);
				    // Specify the content type.
				    uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
					
				    
				    //
					// WRITE TO OUTPUT STREAM
				    //
					
					if( parameters !=null ) {
						
						StringBuilder sw = new StringBuilder();
						
						for( Map.Entry<String, String> e : parameters.entrySet() ) {
							
							sw.append( e.getKey() ).append( '=' ).append( URLEncoder.encode(e.getValue(), "UTF-8")).append('&');
							
						}
						
						DataOutputStream out = new DataOutputStream (uc.getOutputStream ());
					    out.writeBytes( sw.toString() );
					    out.flush ();
					    out.close ();
					    
					}
				    //
					// GET INPUT STREAM
				    //
				    
					InputStream content = (InputStream)uc.getInputStream();

					callback.onSuccess(new InputStreamReader (content));
					
					content.close();
					
				} catch (IOException e) {
					callback.onError(e);
				}
				
				
			}
		};
		
		if( async ) {
			new Thread( task, "Request").start();
		}
		else {
			task.run();
		}

	}
	

}
